﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Security;
using Microsoft.IdentityModel.Claims;
using Veracruz.IdentityModel;
using System.Web;
using System.Configuration.Provider;
using System.ServiceModel;
using Microsoft.IdentityModel.Protocols.WSTrust;
using System.IdentityModel.Tokens;

namespace Veracruz.Providers
{
    /// <summary>
    /// ASPNet membership provider using Veracruz claims
    /// </summary>
    public sealed class ClaimBasedMembershipProvider
        :MembershipProvider
    {
        #region fields
        public override string ApplicationName { get; set; } 
        #endregion

        public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
        {
            //HttpContext.Current.Response.Redirect("http://login.facebook.com");

            base.Initialize(name, config);
        }

        public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
        {
            //call facebook to look up veracruz registered users by email
            MembershipUserCollection __users = new MembershipUserCollection();
            //HACK: abstract the social platform implementation (facebook/live) => Managed Service Engine
            if (ClaimsPrincipal.Current.Identities.Count > 0 && ClaimsPrincipal.Current.Identities[0].IsAuthenticated)
            {
                //Call facebook service
            }
#if MOCK
            else
            {
                __users.Add(GetFakeUser(0));
                __users.Add(GetFakeUser(1));
                __users.Add(GetFakeUser(2));
                __users.Add(GetFakeUser(3));
                __users.Add(GetFakeAdmin());
            }
#endif
            totalRecords = __users.Count;

            return __users;
        }
        public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
        {
            //call facebook to look up veracruz registered users by email
            MembershipUserCollection __users = new MembershipUserCollection();
            //HACK: abstract the social platform implementation (facebook/live) => Managed Service Engine
            if (ClaimsPrincipal.Current.Identities.Count > 0 && ClaimsPrincipal.Current.Identities[0].IsAuthenticated)
            {
                //Call facebook service
                ChannelFactory<ISocialNetworkService> l_channelFactory = new ChannelFactory<ISocialNetworkService>("FacebookService");
                WSTrustClientCredentials clientCreds;
                ISocialNetworkService l_service = WSTrustClientCredentials.ConfigureChannelFactory<ISocialNetworkService>(l_channelFactory, out clientCreds);
                
                SecurityToken __token = HttpContext.Current.Session["CachedToken"] as SecurityToken;
                clientCreds.ActAs = __token;


            }
#if MOCK
            else
            {
                __users.Add(GetFakeUser(0));
                __users.Add(GetFakeUser(1));
                __users.Add(GetFakeUser(2));
                __users.Add(GetFakeUser(3));
                __users.Add(GetFakeAdmin());
            }
#endif
            totalRecords = __users.Count;

            return __users;
        }
        public override MembershipUser GetUser(string username, bool userIsOnline)
        {
            //call facebook and get info for relevant veracruz registered user 
            object __providerKey = null;
            string __email = String.Empty;
            string __pswQuestion = String.Empty;
            string __comment = String.Empty;
            bool __isApproved = true;
            bool __isLockedOut = false;

            MembershipUser __user = new MembershipUser(this.Name, username, __providerKey, __email, __pswQuestion, __comment, __isApproved, __isLockedOut, DateTime.Today, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.MinValue);
            return __user;
        }
        public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
        {
            //call facebook and get info for relevant veracruz registered user 
            string __userName = "UserName";
            string __email = String.Empty;
            string __pswQuestion = String.Empty;
            string __comment = String.Empty;
            bool __isApproved = true;
            bool __isLockedOut = false;

            MembershipUser __user = new MembershipUser(this.Name, __userName, providerUserKey, __email, __pswQuestion, __comment, __isApproved, __isLockedOut, DateTime.Today, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.MinValue);
            return __user;
        }
        public override string GetUserNameByEmail(string email)
        {
            //Look up name from email on facebook
            return email;
        }
        public override bool ValidateUser(string username, string password)
        {
            IClaimsIdentity __claimsIdentity = ClaimsPrincipal.Current.Identity as IClaimsIdentity;
            return __claimsIdentity != null && __claimsIdentity.IsAuthenticated;
        }

        private AuthenticationSchemeClaimValue GetTargetAuthenticationScheme()
        {
            IClaimsIdentity __identity = HttpContext.Current.User.Identity as IClaimsIdentity;

            if (__identity == null)
            {
                throw new ProviderException("Unsupported_Identity");
            }

            Claim __authenticationSchemeClaim = __identity.Claims.Single(c => c.ClaimType == IdentityClaimDefinitions.AuthenticationSchemeClaim);
            return (AuthenticationSchemeClaimValue)Enum.Parse(typeof(AuthenticationSchemeClaimValue), __authenticationSchemeClaim.Value);
            
        }
        private object GetService()
        {
            object __service = null;

            switch (GetTargetAuthenticationScheme())
            {
                case AuthenticationSchemeClaimValue.WindowsLive:
                    
                    break;
                case AuthenticationSchemeClaimValue.Facebook:
                    break;
                default:
                    throw new ApplicationException("Unsupported_Authentication_scheme");
            }
            return __service;
        }

#if MOCK
        private MembershipUser GetFakeUser(int fakeUserIndex)
        {
            return new MembershipUser(this.Name, string.Format("name{0}", fakeUserIndex), null, string.Format("name{0}@internet.com", fakeUserIndex), "pswQuestion", "comment", true, false, DateTime.Today, DateTime.Now, DateTime.Now, DateTime.Today, DateTime.MinValue);
        }
        private MembershipUser GetFakeAdmin()
        {
            return new MembershipUser(this.Name, "Anthony Guérot", null, "anthony_guerot@hotmail.com", "pswQuestion", string.Empty, true, false, DateTime.Today.AddDays(-10), DateTime.Today, DateTime.Today.AddDays(-1), DateTime.Today, DateTime.MinValue); 
        }
#endif        
        
        #region No implementation required for WSS


        public override bool ChangePassword(string username, string oldPassword, string newPassword)
        {
            throw new NotImplementedException();
        }


        public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer)
        {
            throw new NotImplementedException();
        }


        public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
        {
            throw new NotImplementedException();
        }


        public override bool DeleteUser(string username, bool deleteAllRelatedData)
        {
            throw new NotImplementedException();
        }


        public override bool EnablePasswordReset
        {
            get { throw new NotImplementedException(); }
        }


        public override bool EnablePasswordRetrieval
        {
            get { throw new NotImplementedException(); }
        }

        public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
        {
            MembershipUserCollection __users = new MembershipUserCollection();

            __users.Add(GetFakeUser(0));
            __users.Add(GetFakeUser(1));
            __users.Add(GetFakeUser(2));
            __users.Add(GetFakeUser(3));
            __users.Add(GetFakeUser(4));
            __users.Add(GetFakeUser(5));
            __users.Add(GetFakeUser(6));

            totalRecords = __users.Count;

            return __users;

            throw new NotImplementedException();
        }


        public override int GetNumberOfUsersOnline()
        {
            throw new NotImplementedException();
        }


        public override string GetPassword(string username, string answer)
        {
            throw new NotImplementedException();
        }


        public override int MaxInvalidPasswordAttempts
        {
            get { throw new NotImplementedException(); }
        }


        public override int MinRequiredNonAlphanumericCharacters
        {
            get { throw new NotImplementedException(); }
        }


        public override int MinRequiredPasswordLength
        {
            get { throw new NotImplementedException(); }
        }


        public override int PasswordAttemptWindow
        {
            get { throw new NotImplementedException(); }
        }


        public override MembershipPasswordFormat PasswordFormat
        {
            get { throw new NotImplementedException(); }
        }



        public override string PasswordStrengthRegularExpression
        {
            get { throw new NotImplementedException(); }
        }


        public override bool RequiresQuestionAndAnswer
        {
            get { throw new NotImplementedException(); }
        }


        public override bool RequiresUniqueEmail
        {
            get { throw new NotImplementedException(); }
        }


        public override string ResetPassword(string username, string answer)
        {
            throw new NotImplementedException();
        }


        public override bool UnlockUser(string userName)
        {
            throw new NotImplementedException();
        }


        public override void UpdateUser(MembershipUser user)
        {
            throw new NotImplementedException();
        }
        #endregion
    }
}